Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
m2sxxx_eth.c
Go to the documentation of this file.
00001 /** 00002 * @file m2sxxx_eth.c 00003 * @brief SmartFusion2 (M2Sxxx) 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 "m2sxxx.h" 00034 #include "core/net.h" 00035 #include "drivers/m2sxxx_eth.h" 00036 #include "debug.h" 00037 00038 //Underlying network interface 00039 static NetInterface *nicDriverInterface; 00040 00041 //IAR EWARM compiler? 00042 #if defined(__ICCARM__) 00043 00044 //Transmit buffer 00045 #pragma data_alignment = 4 00046 static uint8_t txBuffer[M2SXXX_ETH_TX_BUFFER_COUNT][M2SXXX_ETH_TX_BUFFER_SIZE]; 00047 //Receive buffer 00048 #pragma data_alignment = 4 00049 static uint8_t rxBuffer[M2SXXX_ETH_RX_BUFFER_COUNT][M2SXXX_ETH_RX_BUFFER_SIZE]; 00050 //Transmit DMA descriptors 00051 #pragma data_alignment = 4 00052 static M2sxxxTxDmaDesc txDmaDesc[M2SXXX_ETH_TX_BUFFER_COUNT]; 00053 //Receive DMA descriptors 00054 #pragma data_alignment = 4 00055 static M2sxxxRxDmaDesc rxDmaDesc[M2SXXX_ETH_RX_BUFFER_COUNT]; 00056 00057 //Keil MDK-ARM or GCC compiler? 00058 #else 00059 00060 //Transmit buffer 00061 static uint8_t txBuffer[M2SXXX_ETH_TX_BUFFER_COUNT][M2SXXX_ETH_TX_BUFFER_SIZE] 00062 __attribute__((aligned(4))); 00063 //Receive buffer 00064 static uint8_t rxBuffer[M2SXXX_ETH_RX_BUFFER_COUNT][M2SXXX_ETH_RX_BUFFER_SIZE] 00065 __attribute__((aligned(4))); 00066 //Transmit DMA descriptors 00067 static M2sxxxTxDmaDesc txDmaDesc[M2SXXX_ETH_TX_BUFFER_COUNT] 00068 __attribute__((aligned(4))); 00069 //Receive DMA descriptors 00070 static M2sxxxRxDmaDesc rxDmaDesc[M2SXXX_ETH_RX_BUFFER_COUNT] 00071 __attribute__((aligned(4))); 00072 00073 #endif 00074 00075 //Pointer to the current TX DMA descriptor 00076 static M2sxxxTxDmaDesc *txCurDmaDesc; 00077 //Pointer to the current RX DMA descriptor 00078 static M2sxxxRxDmaDesc *rxCurDmaDesc; 00079 00080 00081 /** 00082 * @brief M2Sxxx Ethernet MAC driver 00083 **/ 00084 00085 const NicDriver m2sxxxEthDriver = 00086 { 00087 NIC_TYPE_ETHERNET, 00088 ETH_MTU, 00089 m2sxxxEthInit, 00090 m2sxxxEthTick, 00091 m2sxxxEthEnableIrq, 00092 m2sxxxEthDisableIrq, 00093 m2sxxxEthEventHandler, 00094 m2sxxxEthSendPacket, 00095 m2sxxxEthSetMulticastFilter, 00096 m2sxxxEthUpdateMacConfig, 00097 m2sxxxEthWritePhyReg, 00098 m2sxxxEthReadPhyReg, 00099 TRUE, 00100 TRUE, 00101 TRUE, 00102 FALSE 00103 }; 00104 00105 00106 /** 00107 * @brief M2Sxxx Ethernet MAC initialization 00108 * @param[in] interface Underlying network interface 00109 * @return Error code 00110 **/ 00111 00112 error_t m2sxxxEthInit(NetInterface *interface) 00113 { 00114 error_t error; 00115 00116 //Debug message 00117 TRACE_INFO("Initializing M2Sxxx Ethernet MAC...\r\n"); 00118 00119 //Save underlying network interface 00120 nicDriverInterface = interface; 00121 00122 //Disable EDAC feature 00123 SYSREG->EDAC_CR &= ~(EDAC_CR_MAC_EDAC_RX_EN | EDAC_CR_MAC_EDAC_TX_EN); 00124 00125 //Reset the MAC module 00126 MAC->CFG1 = CFG1_SOFT_RESET | CFG1_RESET_RX_MAC_CTRL | 00127 CFG1_RESET_TX_MAC_CTRL | CFG1_RESET_RX_FUNCTION | CFG1_RESET_TX_FUNCTION; 00128 00129 //Reset the interface module 00130 MAC->INTERFACE_CTRL = INTERFACE_CTRL_RESET; 00131 00132 //Reset FIFOs 00133 MAC->FIFO_CFG0 = FIFO_CFG0_HSTRSTFT | FIFO_CFG0_HSTRSTST | 00134 FIFO_CFG0_HSTRSTFR | FIFO_CFG0_HSTRSTSR | FIFO_CFG0_HSTRSTWT; 00135 00136 //Take the MAC module out of reset 00137 MAC->CFG1 = 0; 00138 //Take the interface module out of reset 00139 MAC->INTERFACE_CTRL = 0; 00140 //Take the FIFOs out of reset 00141 MAC->FIFO_CFG0 = 0; 00142 00143 //Select interface mode (MII, RMII, GMII or TBI) 00144 m2sxxxEthInitGpio(interface); 00145 00146 //Select the proper divider for the MDC clock 00147 MAC->MII_CONFIG = MII_CONFIG_CLKSEL_DIV28; 00148 00149 //PHY transceiver initialization 00150 error = interface->phyDriver->init(interface); 00151 //Failed to initialize PHY transceiver? 00152 if(error) 00153 return error; 00154 00155 //Set the upper 16 bits of the MAC address 00156 MAC->STATION_ADDRESS2 = (interface->macAddr.b[0] << 16) | 00157 (interface->macAddr.b[1] << 24); 00158 00159 //Set the lower 32 bits of the MAC address 00160 MAC->STATION_ADDRESS1 = interface->macAddr.b[2] | 00161 (interface->macAddr.b[3] << 8) | 00162 (interface->macAddr.b[4] << 16) | 00163 (interface->macAddr.b[5] << 24); 00164 00165 //Maximum frame length to be accepted 00166 MAC->MAX_FRAME_LENGTH = 1518; 00167 00168 //Disable flow control 00169 MAC->CFG1 = 0; 00170 00171 //All short frames will be zero-padded to 60 bytes and a valid CRC is then appended 00172 MAC->CFG2 = CFG2_PREAMBLE_7 | CFG2_INTERFACE_MODE_NIBBLE | 00173 CFG2_LENGTH_FIELD_CHECK | CFG2_PAD_CRC_EN | CFG2_CRC_EN; 00174 00175 //Enable TX and RX FIFOs 00176 MAC->FIFO_CFG0 = FIFO_CFG0_FTFENREQ | FIFO_CFG0_STFENREQ | 00177 FIFO_CFG0_FRFENREQ | FIFO_CFG0_SRFENREQ | FIFO_CFG0_WTMENREQ; 00178 00179 //Use default FIFO configuration 00180 MAC->FIFO_CFG1 = FIFO_CFG1_DEFAULT_VALUE; 00181 MAC->FIFO_CFG2 = FIFO_CFG2_DEFAULT_VALUE; 00182 MAC->FIFO_CFG3 = FIFO_CFG3_DEFAULT_VALUE; 00183 00184 //Drop frames less than 64 bytes 00185 MAC->FIFO_CFG5 = FIFO_CFG5_HSTDRPLT64 | FIFO_CFG5_HSTFLTRFRMDC; 00186 00187 //Specify the statistics vectors that will be checked 00188 MAC->FIFO_CFG5 &= ~(FIFO_CFG5_TRUNCATED | FIFO_CFG5_RECEPTION_OK | 00189 FIFO_CFG5_INVALID_CRC | FIFO_CFG5_RECEIVE_ERROR); 00190 00191 //Configure frame filtering 00192 MAC->FIFO_CFG4 = FIFO_CFG4_TRUNCATED | 00193 FIFO_CFG4_INVALID_CRC | FIFO_CFG4_RECEIVE_ERROR; 00194 00195 //Initialize DMA descriptor lists 00196 m2sxxxEthInitDmaDesc(interface); 00197 00198 //Enable the desired Ethernet interrupts 00199 MAC->DMA_IRQ_MASK = DMA_IRQ_MASK_RX_PKT_RECEIVED | DMA_IRQ_MASK_TX_PKT_SENT; 00200 00201 //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority) 00202 NVIC_SetPriorityGrouping(M2SXXX_ETH_IRQ_PRIORITY_GROUPING); 00203 00204 //Configure Ethernet interrupt priority 00205 NVIC_SetPriority(EthernetMAC_IRQn, NVIC_EncodePriority(M2SXXX_ETH_IRQ_PRIORITY_GROUPING, 00206 M2SXXX_ETH_IRQ_GROUP_PRIORITY, M2SXXX_ETH_IRQ_SUB_PRIORITY)); 00207 00208 //Enable transmission and reception 00209 MAC->CFG1 |= CFG1_TX_EN | CFG1_RX_EN; 00210 //Enable the DMA transfer of received packets 00211 MAC->DMA_RX_CTRL = DMA_RX_CTRL_RX_EN; 00212 00213 //Accept any packets from the upper layer 00214 osSetEvent(&interface->nicTxEvent); 00215 00216 //Successful initialization 00217 return NO_ERROR; 00218 } 00219 00220 00221 //SF2-STARTER-KIT-ES-2 evaluation board? 00222 #if defined(USE_SF2_STARTER_KIT_ES_2) 00223 00224 /** 00225 * @brief GPIO configuration 00226 * @param[in] interface Underlying network interface 00227 **/ 00228 00229 void m2sxxxEthInitGpio(NetInterface *interface) 00230 { 00231 //Select MII interface mode 00232 SYSREG->MAC_CR = MAC_CR_ETH_PHY_MODE_MII; 00233 } 00234 00235 #endif 00236 00237 00238 /** 00239 * @brief Initialize DMA descriptor lists 00240 * @param[in] interface Underlying network interface 00241 **/ 00242 00243 void m2sxxxEthInitDmaDesc(NetInterface *interface) 00244 { 00245 uint_t i; 00246 00247 //Initialize TX DMA descriptor list 00248 for(i = 0; i < M2SXXX_ETH_TX_BUFFER_COUNT; i++) 00249 { 00250 //Transmit buffer address 00251 txDmaDesc[i].addr = (uint32_t) txBuffer[i]; 00252 //The descriptor is initially owned by the user 00253 txDmaDesc[i].size = DMA_DESC_EMPTY_FLAG; 00254 //Next descriptor address 00255 txDmaDesc[i].next = (uint32_t) &txDmaDesc[i + 1]; 00256 } 00257 00258 //The last descriptor is chained to the first entry 00259 txDmaDesc[i - 1].next = (uint32_t) &txDmaDesc[0]; 00260 //Point to the very first descriptor 00261 txCurDmaDesc = &txDmaDesc[0]; 00262 00263 //Initialize RX DMA descriptor list 00264 for(i = 0; i < M2SXXX_ETH_RX_BUFFER_COUNT; i++) 00265 { 00266 //Receive buffer address 00267 rxDmaDesc[i].addr = (uint32_t) rxBuffer[i]; 00268 //The descriptor is initially owned by the DMA 00269 rxDmaDesc[i].size = DMA_DESC_EMPTY_FLAG; 00270 //Next descriptor address 00271 rxDmaDesc[i].next = (uint32_t) &rxDmaDesc[i + 1]; 00272 } 00273 00274 //The last descriptor is chained to the first entry 00275 rxDmaDesc[i - 1].next = (uint32_t) &rxDmaDesc[0]; 00276 //Point to the very first descriptor 00277 rxCurDmaDesc = &rxDmaDesc[0]; 00278 00279 //Start location of the TX descriptor list 00280 MAC->DMA_TX_DESC = (uint32_t) txDmaDesc; 00281 //Start location of the RX descriptor list 00282 MAC->DMA_RX_DESC = (uint32_t) rxDmaDesc; 00283 } 00284 00285 00286 /** 00287 * @brief M2Sxxx Ethernet MAC timer handler 00288 * 00289 * This routine is periodically called by the TCP/IP stack to 00290 * handle periodic operations such as polling the link state 00291 * 00292 * @param[in] interface Underlying network interface 00293 **/ 00294 00295 void m2sxxxEthTick(NetInterface *interface) 00296 { 00297 //Handle periodic operations 00298 interface->phyDriver->tick(interface); 00299 } 00300 00301 00302 /** 00303 * @brief Enable interrupts 00304 * @param[in] interface Underlying network interface 00305 **/ 00306 00307 void m2sxxxEthEnableIrq(NetInterface *interface) 00308 { 00309 //Enable Ethernet MAC interrupts 00310 NVIC_EnableIRQ(EthernetMAC_IRQn); 00311 //Enable Ethernet PHY interrupts 00312 interface->phyDriver->enableIrq(interface); 00313 } 00314 00315 00316 /** 00317 * @brief Disable interrupts 00318 * @param[in] interface Underlying network interface 00319 **/ 00320 00321 void m2sxxxEthDisableIrq(NetInterface *interface) 00322 { 00323 //Disable Ethernet MAC interrupts 00324 NVIC_DisableIRQ(EthernetMAC_IRQn); 00325 //Disable Ethernet PHY interrupts 00326 interface->phyDriver->disableIrq(interface); 00327 } 00328 00329 00330 /** 00331 * @brief M2Sxxx Ethernet MAC interrupt service routine 00332 **/ 00333 00334 void EthernetMAC_IRQHandler(void) 00335 { 00336 bool_t flag; 00337 uint32_t status; 00338 00339 //Enter interrupt service routine 00340 osEnterIsr(); 00341 00342 //This flag will be set if a higher priority task must be woken 00343 flag = FALSE; 00344 00345 //Read interrupt status register 00346 status = MAC->DMA_IRQ; 00347 00348 //A packet has been transmitted? 00349 if(status & DMA_IRQ_TX_PKT_SENT) 00350 { 00351 //Clear TX interrupt flag 00352 MAC->DMA_TX_STATUS = DMA_TX_STATUS_TX_PKT_SENT; 00353 00354 //Check whether the TX buffer is available for writing 00355 if(txCurDmaDesc->size & DMA_DESC_EMPTY_FLAG) 00356 { 00357 //Notify the TCP/IP stack that the transmitter is ready to send 00358 flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent); 00359 } 00360 } 00361 00362 //A packet has been received? 00363 if(status & DMA_IRQ_RX_PKT_RECEIVED) 00364 { 00365 //Disable RX interrupt 00366 MAC->DMA_IRQ_MASK &= ~DMA_IRQ_MASK_RX_PKT_RECEIVED; 00367 00368 //Set event flag 00369 nicDriverInterface->nicEvent = TRUE; 00370 //Notify the TCP/IP stack of the event 00371 flag |= osSetEventFromIsr(&netEvent); 00372 } 00373 00374 //Leave interrupt service routine 00375 osExitIsr(flag); 00376 } 00377 00378 00379 /** 00380 * @brief M2Sxxx Ethernet MAC event handler 00381 * @param[in] interface Underlying network interface 00382 **/ 00383 00384 void m2sxxxEthEventHandler(NetInterface *interface) 00385 { 00386 //Packet received? 00387 if(MAC->DMA_RX_STATUS & DMA_RX_STATUS_RX_PKT_RECEIVED) 00388 { 00389 //Process all the pending packets 00390 while(MAC->DMA_RX_STATUS & DMA_RX_STATUS_RX_PKT_RECEIVED) 00391 { 00392 //Clear RX interrupt flag 00393 MAC->DMA_RX_STATUS = DMA_RX_STATUS_RX_PKT_RECEIVED; 00394 //Read incoming packet 00395 m2sxxxEthReceivePacket(interface); 00396 } 00397 } 00398 00399 //Re-enable Ethernet interrupts 00400 MAC->DMA_IRQ_MASK = DMA_IRQ_MASK_RX_PKT_RECEIVED | DMA_IRQ_MASK_TX_PKT_SENT; 00401 } 00402 00403 00404 /** 00405 * @brief Send a packet 00406 * @param[in] interface Underlying network interface 00407 * @param[in] buffer Multi-part buffer containing the data to send 00408 * @param[in] offset Offset to the first data byte 00409 * @return Error code 00410 **/ 00411 00412 error_t m2sxxxEthSendPacket(NetInterface *interface, 00413 const NetBuffer *buffer, size_t offset) 00414 { 00415 size_t length; 00416 00417 //Retrieve the length of the packet 00418 length = netBufferGetLength(buffer) - offset; 00419 00420 //Check the frame length 00421 if(length > M2SXXX_ETH_TX_BUFFER_SIZE) 00422 { 00423 //The transmitter can accept another packet 00424 osSetEvent(&interface->nicTxEvent); 00425 //Report an error 00426 return ERROR_INVALID_LENGTH; 00427 } 00428 00429 //Make sure the current buffer is available for writing 00430 if(!(txCurDmaDesc->size & DMA_DESC_EMPTY_FLAG)) 00431 return ERROR_FAILURE; 00432 00433 //Copy user data to the transmit buffer 00434 netBufferRead((uint8_t *) txCurDmaDesc->addr, buffer, offset, length); 00435 00436 //Set the packet length and give the ownership of the descriptor to the DMA 00437 txCurDmaDesc->size = length & DMA_DESC_SIZE_MASK; 00438 00439 //Check whether DMA transfers are suspended 00440 if(!(MAC->DMA_TX_CTRL & DMA_TX_CTRL_TX_EN)) 00441 { 00442 //Set the start position in the ring buffer 00443 MAC->DMA_TX_DESC = (uint32_t) txCurDmaDesc; 00444 } 00445 00446 //Instruct the DMA controller to transfer the packet 00447 MAC->DMA_TX_CTRL = DMA_TX_CTRL_TX_EN; 00448 00449 //Point to the next descriptor in the list 00450 txCurDmaDesc = (M2sxxxTxDmaDesc *) txCurDmaDesc->next; 00451 00452 //Check whether the next buffer is available for writing 00453 if(txCurDmaDesc->size & DMA_DESC_EMPTY_FLAG) 00454 { 00455 //The transmitter can accept another packet 00456 osSetEvent(&interface->nicTxEvent); 00457 } 00458 00459 //Data successfully written 00460 return NO_ERROR; 00461 } 00462 00463 00464 /** 00465 * @brief Receive a packet 00466 * @param[in] interface Underlying network interface 00467 * @return Error code 00468 **/ 00469 00470 error_t m2sxxxEthReceivePacket(NetInterface *interface) 00471 { 00472 error_t error; 00473 size_t n; 00474 00475 //The current buffer is available for reading? 00476 if(!(rxCurDmaDesc->size & DMA_DESC_EMPTY_FLAG)) 00477 { 00478 //Retrieve the length of the frame 00479 n = rxCurDmaDesc->size & DMA_DESC_SIZE_MASK; 00480 //Limit the number of data to read 00481 n = MIN(n, M2SXXX_ETH_RX_BUFFER_SIZE); 00482 00483 //Pass the packet to the upper layer 00484 nicProcessPacket(interface, (uint8_t *) rxCurDmaDesc->addr, n); 00485 00486 //Give the ownership of the descriptor back to the DMA 00487 rxCurDmaDesc->size = DMA_DESC_EMPTY_FLAG; 00488 00489 //Check whether DMA transfers are suspended 00490 if(!(MAC->DMA_RX_CTRL & DMA_RX_CTRL_RX_EN)) 00491 { 00492 //Set the start position in the ring buffer 00493 MAC->DMA_RX_DESC = (uint32_t) rxCurDmaDesc; 00494 } 00495 00496 //Enable the DMA transfer of received packets 00497 MAC->DMA_RX_CTRL = DMA_RX_CTRL_RX_EN; 00498 //Point to the next descriptor in the list 00499 rxCurDmaDesc = (M2sxxxRxDmaDesc *) rxCurDmaDesc->next; 00500 00501 //Valid packet received 00502 error = NO_ERROR; 00503 } 00504 else 00505 { 00506 //Check whether DMA transfers are suspended 00507 if(!(MAC->DMA_RX_CTRL & DMA_RX_CTRL_RX_EN)) 00508 { 00509 //Set the start position in the ring buffer 00510 MAC->DMA_RX_DESC = (uint32_t) rxCurDmaDesc; 00511 } 00512 00513 //Enable the DMA transfer of received packets 00514 MAC->DMA_RX_CTRL = DMA_RX_CTRL_RX_EN; 00515 00516 //No more data in the receive buffer 00517 error = ERROR_BUFFER_EMPTY; 00518 } 00519 00520 //Return status code 00521 return error; 00522 } 00523 00524 00525 /** 00526 * @brief Configure multicast MAC address filtering 00527 * @param[in] interface Underlying network interface 00528 * @return Error code 00529 **/ 00530 00531 error_t m2sxxxEthSetMulticastFilter(NetInterface *interface) 00532 { 00533 //SmartFusion2 Ethernet MAC does not implement any hash table 00534 return NO_ERROR; 00535 } 00536 00537 00538 /** 00539 * @brief Adjust MAC configuration parameters for proper operation 00540 * @param[in] interface Underlying network interface 00541 * @return Error code 00542 **/ 00543 00544 error_t m2sxxxEthUpdateMacConfig(NetInterface *interface) 00545 { 00546 uint32_t temp; 00547 00548 //10BASE-T or 100BASE-TX operation mode? 00549 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS) 00550 { 00551 //The link operates at 100 Mbps 00552 temp = SYSREG->MAC_CR & ~MAC_CR_ETH_LINE_SPEED; 00553 SYSREG->MAC_CR = temp | MAC_CR_ETH_LINE_SPEED_100MBPS; 00554 00555 //Configure the RMII module with the current operating speed 00556 MAC->INTERFACE_CTRL |= INTERFACE_CTRL_SPEED; 00557 00558 //Use nibble mode 00559 temp = MAC->CFG2 & ~CFG2_INTERFACE_MODE; 00560 MAC->CFG2 = temp | CFG2_INTERFACE_MODE_NIBBLE; 00561 } 00562 else 00563 { 00564 //The link operates at 10 Mbps 00565 temp = SYSREG->MAC_CR & ~MAC_CR_ETH_LINE_SPEED; 00566 SYSREG->MAC_CR = temp | MAC_CR_ETH_LINE_SPEED_10MBPS; 00567 00568 //Configure the RMII module with the current operating speed 00569 MAC->INTERFACE_CTRL &= ~INTERFACE_CTRL_SPEED; 00570 00571 //Use nibble mode 00572 temp = MAC->CFG2 & ~CFG2_INTERFACE_MODE; 00573 MAC->CFG2 = temp | CFG2_INTERFACE_MODE_NIBBLE; 00574 } 00575 00576 //Half-duplex or full-duplex mode? 00577 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE) 00578 { 00579 //Configure MAC to operate in full-duplex mode 00580 MAC->CFG2 |= CFG2_FULL_DUPLEX; 00581 MAC->FIFO_CFG5 &= ~FIFO_CFG5_CFGHDPLX; 00582 } 00583 else 00584 { 00585 //Configure MAC to operate in half-duplex mode 00586 MAC->CFG2 &= ~CFG2_FULL_DUPLEX; 00587 MAC->FIFO_CFG5 |= FIFO_CFG5_CFGHDPLX; 00588 } 00589 00590 //Successful processing 00591 return NO_ERROR; 00592 } 00593 00594 00595 /** 00596 * @brief Write PHY register 00597 * @param[in] phyAddr PHY address 00598 * @param[in] regAddr Register address 00599 * @param[in] data Register value 00600 **/ 00601 00602 void m2sxxxEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data) 00603 { 00604 //Set PHY address and register address 00605 MAC->MII_ADDRESS = (phyAddr << MII_ADDRESS_PHY_ADDR_POS) | regAddr; 00606 //Start a write operation 00607 MAC->MII_CTRL = data; 00608 00609 //Wait for the write to complete 00610 while(MAC->MII_INDICATORS & MII_INDICATORS_BUSY); 00611 } 00612 00613 00614 /** 00615 * @brief Read PHY register 00616 * @param[in] phyAddr PHY address 00617 * @param[in] regAddr Register address 00618 * @return Register value 00619 **/ 00620 00621 uint16_t m2sxxxEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr) 00622 { 00623 //Set PHY address and register address 00624 MAC->MII_ADDRESS = (phyAddr << MII_ADDRESS_PHY_ADDR_POS) | regAddr; 00625 //Start a read operation 00626 MAC->MII_COMMAND = MII_COMMAND_READ; 00627 00628 //Wait for the read to complete 00629 while(MAC->MII_INDICATORS & MII_INDICATORS_BUSY); 00630 00631 //Clear command register 00632 MAC->MII_COMMAND = 0; 00633 //Return PHY register contents 00634 return MAC->MII_STATUS; 00635 } 00636
Generated on Tue Jul 12 2022 17:10:14 by
