This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
EtherDev_LAN8720.c
00001 /* 00002 FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd. 00003 00004 00005 *************************************************************************** 00006 * * 00007 * FreeRTOS tutorial books are available in pdf and paperback. * 00008 * Complete, revised, and edited pdf reference manuals are also * 00009 * available. * 00010 * * 00011 * Purchasing FreeRTOS documentation will not only help you, by * 00012 * ensuring you get running as quickly as possible and with an * 00013 * in-depth knowledge of how to use FreeRTOS, it will also help * 00014 * the FreeRTOS project to continue with its mission of providing * 00015 * professional grade, cross platform, de facto standard solutions * 00016 * for microcontrollers - completely free of charge! * 00017 * * 00018 * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * 00019 * * 00020 * Thank you for using FreeRTOS, and thank you for your support! * 00021 * * 00022 *************************************************************************** 00023 00024 00025 This file is part of the FreeRTOS distribution. 00026 00027 FreeRTOS is free software; you can redistribute it and/or modify it under 00028 the terms of the GNU General Public License (version 2) as published by the 00029 Free Software Foundation AND MODIFIED BY the FreeRTOS exception. 00030 >>>NOTE<<< The modification to the GPL is included to allow you to 00031 distribute a combined work that includes FreeRTOS without being obliged to 00032 provide the source code for proprietary components outside of the FreeRTOS 00033 kernel. FreeRTOS is distributed in the hope that it will be useful, but 00034 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00035 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00036 more details. You should have received a copy of the GNU General Public 00037 License and the FreeRTOS license exception along with FreeRTOS; if not it 00038 can be viewed here: http://www.freertos.org/a00114.html and also obtained 00039 by writing to Richard Barry, contact details for whom are available on the 00040 FreeRTOS WEB site. 00041 00042 1 tab == 4 spaces! 00043 00044 http://www.FreeRTOS.org - Documentation, latest information, license and 00045 contact details. 00046 00047 http://www.SafeRTOS.com - A version that is certified for use in safety 00048 critical systems. 00049 00050 http://www.OpenRTOS.com - Commercial support, development, porting, 00051 licensing and training services. 00052 */ 00053 00054 /* Originally adapted from file written by Andreas Dannenberg. Supplied with permission. */ 00055 /* 00056 * Modified for MiMic by R.Iizuka. 2011.08.27 00057 * http://nyatla.jp/mimic 00058 */ 00059 00060 00061 #include "NyLPC_config.h" 00062 #if NyLPC_MCU==NyLPC_MCU_LPC17xx 00063 #include "EtherDev_LAN8720_protected.h" 00064 #include "../NyLPC_cEthernetMM.h" 00065 #include "LPC17xx.h" 00066 #include "NyLPC_os.h" 00067 00068 #define LAN8720_ID 0x0007C0F0 /* PHY Identifier */ 00069 00070 /* LAN8720 PHY Registers */ 00071 #define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ 00072 #define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ 00073 #define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ 00074 #define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ 00075 #define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ 00076 #define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ 00077 #define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ 00078 00079 /* PHY Extended Registers */ 00080 #define PHY_REG_MODE_CTRL 17 00081 #define PHY_REG_SPECIAL_MODE 18 00082 #define PHY_REG_SYMBOL_ERR_CNT 26 00083 #define PHY_REG_SPECIAL_CTRL 27 00084 #define PHY_REG_INT_SOURCE 29 00085 #define PHY_REG_INT_MASK 30 00086 #define PHY_REG_PHY_CTRL 31 00087 00088 #define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ 00089 #define PHY_AUTO_NEG_COMPLETE 0x1000 /* Auto negotiation have finished. */ 00090 00091 #define PHY_SPEED_FDUPLX 0x0010 /* Full Duplex */ 00092 #define PHY_SPEED_100 0x0008 /* 100Mbit */ 00093 00094 00095 #ifndef configEMAC_INTERRUPT_PRIORITY 00096 #define configEMAC_INTERRUPT_PRIORITY 5 00097 #endif 00098 00099 /* Time to wait between each inspection of the link status. */ 00100 #define emacWAIT_FOR_LINK_TO_ESTABLISH_MS 500 00101 00102 /* Short delay used in several places during the initialisation process. */ 00103 #define emacSHORT_DELAY_MS 10 00104 00105 /* Hardware specific bit definitions. */ 00106 #define emacPINSEL2_VALUE ( 0x50150105 ) 00107 00108 00109 /*-----------------------------------------------------------*/ 00110 00111 /* Setup the IO and peripherals required for Ethernet communication.*/ 00112 static void prvSetupEMACHardware( void ); 00113 /* Control the auto negotiate process.*/ 00114 static void prvConfigurePHY( void ); 00115 /* 00116 * Wait for a link to be established, then setup the PHY according to the link 00117 * parameters. 00118 */ 00119 static long prvSetupLinkStatus( void ); 00120 00121 00122 00123 00124 static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param); 00125 static void stop(void); 00126 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); 00127 static void releaseTxBuf(void* i_buf); 00128 00129 /** EMAC ISRハンドラ*/ 00130 static void emacIsrHandler(unsigned long i_status); 00131 00132 /*-----------------------------------------------------------*/ 00133 00134 00135 const static struct TiEthernetDevice _interface= 00136 { 00137 "LAN8720", 00138 start, 00139 stop, 00140 EthDev_LPC17xx_getRxEthFrame, 00141 EthDev_LPC17xx_nextRxEthFrame, 00142 allocTxBuf, 00143 releaseTxBuf, 00144 EthDev_LPC17xx_sendTxEthFrame, 00145 EthDev_LPC17xx_processTx 00146 }; 00147 static void* _event_param; 00148 static NyLPC_TiEthernetDevice_onEvent _event_handler; 00149 00150 /* 00151 * EthernetDeviceのファクトリー関数。インターフェイスを生成できればtrue 00152 * 00153 */ 00154 NyLPC_TBool EthDev_LAN8720_getInterface( 00155 const struct TiEthernetDevice** o_dev) 00156 { 00157 unsigned long ulID1, ulID2; 00158 NyLPC_TBool ret=NyLPC_TBool_TRUE; 00159 //Reset MCU Interface. and wait for reset. 00160 prvSetupEMACHardware(); 00161 //Check peripheral name 00162 ulID1 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR1, &ret ); 00163 ulID2 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR2, &ret ); 00164 if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) != LAN8720_ID) 00165 { 00166 return NyLPC_TBool_FALSE; 00167 } 00168 *o_dev=&_interface; 00169 LPC_EMAC->TxProduceIndex = 0; 00170 LPC_EMAC->RxConsumeIndex = 0; 00171 return NyLPC_TBool_TRUE; 00172 } 00173 00174 00175 00176 /*********************************************************************** 00177 * RXバッファ関連の定義 00178 ***********************************************************************/ 00179 #define ETH_TX_BUF_BASE (void*)(ETH_BUF_BASE+ETH_FRAG_SIZE*NUM_RX_FRAG) 00180 00181 static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param) 00182 { 00183 //ISRw割り込み設定 00184 NyLPC_cIsr_setEnetISR(emacIsrHandler); 00185 _event_handler=i_handler; 00186 _event_param=i_param; 00187 /* Set the Ethernet MAC Address registers */ 00188 LPC_EMAC->SA0 = (((uint32_t)(i_eth_addr->addr[0])) << 8 ) | i_eth_addr->addr[1]; 00189 LPC_EMAC->SA1 = (((uint32_t)(i_eth_addr->addr[2])) << 8 ) | i_eth_addr->addr[3]; 00190 LPC_EMAC->SA2 = (((uint32_t)(i_eth_addr->addr[4])) << 8 ) | i_eth_addr->addr[5]; 00191 00192 //TXメモリマネージャの準備 00193 NyLPC_cEthernetMM_initialize(ETH_TX_BUF_BASE); 00194 /* Initialize Tx and Rx DMA Descriptors */ 00195 EthDev_LPC17xx_prevRxDescriptor(); 00196 EthDev_LPC17xx_prevTxDescriptor(); 00197 00198 /* Setup the PHY. */ 00199 prvConfigurePHY(); 00200 00201 //wait for Link up... 00202 while(!prvSetupLinkStatus()) 00203 { 00204 NyLPC_cThread_sleep(100); 00205 } 00206 00207 /* Receive Broadcast and Perfect Match Packets */ 00208 LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN | RFC_MCAST_EN; 00209 00210 //Ethernetの割込み開始設定 00211 NyLPC_cIsr_enterCritical(); 00212 { 00213 /* Reset all interrupts */ 00214 LPC_EMAC->IntClear = 0xffff; 00215 LPC_EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE ); 00216 /* Enable receive and transmit mode of MAC Ethernet core */ 00217 LPC_EMAC->Command |= ( CR_RX_EN | CR_TX_EN ); 00218 LPC_EMAC->MAC1 |= MAC1_REC_EN; 00219 00220 /* Set the interrupt priority to the max permissible to cause some 00221 interrupt nesting. */ 00222 NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY ); 00223 00224 /* Enable the interrupt. */ 00225 NVIC_EnableIRQ( ENET_IRQn ); 00226 } 00227 NyLPC_cIsr_exitCritical(); 00228 00229 return NyLPC_TBool_TRUE; 00230 } 00231 static void stop(void) 00232 { 00233 NyLPC_cIsr_enterCritical(); 00234 { 00235 LPC_EMAC->IntEnable = (~(INT_RX_DONE|INT_TX_DONE))&LPC_EMAC->IntEnable; 00236 NVIC_DisableIRQ( ENET_IRQn ); 00237 } 00238 NyLPC_cIsr_exitCritical(); 00239 LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN ); 00240 LPC_EMAC->MAC1 &= ~MAC1_REC_EN; 00241 //ISR割り込み解除 00242 NyLPC_cIsr_setEnetISR(NULL); 00243 //TXメモリマネージャの終了 00244 NyLPC_cEthernetMM_finalize(); 00245 } 00246 00247 00248 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) 00249 { 00250 return NyLPC_cEthernetMM_alloc(i_hint,o_size); 00251 } 00252 static void releaseTxBuf(void* i_buf) 00253 { 00254 NyLPC_cEthernetMM_release(i_buf); 00255 } 00256 00257 00258 00259 /******************************************************************************** 00260 * Private functions 00261 *******************************************************************************/ 00262 00263 /*-----------------------------------------------------------*/ 00264 00265 /*-----------------------------------------------------------*/ 00266 00267 static void prvSetupEMACHardware( void ) 00268 { 00269 unsigned short us; 00270 long x; 00271 NyLPC_TBool lDummy; 00272 00273 /* Power Up the EMAC controller. */ 00274 LPC_SC->PCONP |= 0x40000000; 00275 NyLPC_cThread_sleep( emacSHORT_DELAY_MS); 00276 00277 /* Enable P1 Ethernet Pins. */ 00278 LPC_PINCON->PINSEL2 = emacPINSEL2_VALUE; 00279 LPC_PINCON->PINSEL3 = ( LPC_PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005; 00280 00281 /* Reset all EMAC internal modules. */ 00282 LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; 00283 LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES| CR_PASS_RUNT_FRM; 00284 /* A short delay after reset. */ 00285 NyLPC_cThread_sleep( emacSHORT_DELAY_MS); 00286 00287 /* Initialize MAC control registers. */ 00288 LPC_EMAC->MAC1 = MAC1_PASS_ALL; 00289 LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; 00290 LPC_EMAC->MAXF = ETH_MAX_FLEN; 00291 LPC_EMAC->CLRT = CLRT_DEF; 00292 LPC_EMAC->IPGR = IPGR_DEF; 00293 00294 /*PCLK=18MHz, clock select=6, MDC=18/6=3MHz */ // I don't think so! 00295 /* Enable Reduced MII interface. */ 00296 LPC_EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII; 00297 NyLPC_cThread_sleep( emacSHORT_DELAY_MS); 00298 LPC_EMAC->MCFG = MCFG_CLK_DIV20; 00299 00300 /* Enable Reduced MII interface. */ 00301 LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT; 00302 00303 /* Reset Reduced MII Logic. */ 00304 LPC_EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED; 00305 NyLPC_cThread_sleep( emacSHORT_DELAY_MS); 00306 LPC_EMAC->SUPP = SUPP_SPEED; 00307 00308 /* Put the PHY in reset mode */ 00309 EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); 00310 NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5); 00311 00312 /* Wait for hardware reset to end. */ 00313 for( x = 0; x < 100; x++ ) 00314 { 00315 NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); 00316 us = EthDev_LPC17xx_prvReadPHY( PHY_REG_BMCR, &lDummy ); 00317 if( !( us & MCFG_RES_MII ) ) 00318 { 00319 /* Reset complete */ 00320 break; 00321 } 00322 } 00323 } 00324 00325 00326 /** 00327 * Private function depend on configulation. 00328 * デバイス依存部分 00329 */ 00330 00331 00332 /* for LPC1769 00333 */ 00334 static void prvConfigurePHY( void ) 00335 { 00336 unsigned short us; 00337 long x; 00338 NyLPC_TBool lDummy; 00339 /* Auto negotiate the configuration. */ 00340 if( EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) 00341 { 00342 NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); 00343 00344 for( x = 0; x < 10; x++ ) 00345 { 00346 us = EthDev_LPC17xx_prvReadPHY( PHY_REG_PHY_CTRL, &lDummy ); 00347 if( us & PHY_AUTO_NEG_COMPLETE ) 00348 { 00349 break; 00350 } 00351 NyLPC_cThread_sleep( emacWAIT_FOR_LINK_TO_ESTABLISH_MS); 00352 } 00353 } 00354 } 00355 00356 static long prvSetupLinkStatus( void ) 00357 { 00358 long x; 00359 unsigned short usLinkStatus; 00360 NyLPC_TBool lReturn=NyLPC_TBool_TRUE; 00361 00362 /* Wait with timeout for the link to be established. */ 00363 for( x = 0; x < 10; x++ ) 00364 { 00365 usLinkStatus = EthDev_LPC17xx_prvReadPHY (PHY_REG_PHY_CTRL, &lReturn ); 00366 if( usLinkStatus & PHY_AUTO_NEG_COMPLETE ) 00367 { 00368 /* Link is established. */ 00369 lReturn = NyLPC_TBool_TRUE; 00370 break; 00371 } 00372 NyLPC_cThread_sleep( emacWAIT_FOR_LINK_TO_ESTABLISH_MS); 00373 } 00374 00375 if( lReturn == NyLPC_TBool_TRUE ) 00376 { 00377 /* Configure Full/Half Duplex mode. */ 00378 if (usLinkStatus & PHY_SPEED_FDUPLX ) 00379 { 00380 /* Full duplex is enabled. */ 00381 LPC_EMAC->MAC2 |= MAC2_FULL_DUP; 00382 LPC_EMAC->Command |= CR_FULL_DUP; 00383 LPC_EMAC->IPGT = IPGT_FULL_DUP; 00384 } 00385 else 00386 { 00387 /* Half duplex mode. */ 00388 LPC_EMAC->IPGT = IPGT_HALF_DUP; 00389 } 00390 00391 /* Configure 100MBit/10MBit mode. */ 00392 if( !(usLinkStatus & PHY_SPEED_100) ) 00393 { 00394 /* 10MBit mode. */ 00395 LPC_EMAC->SUPP = 0; 00396 } 00397 else 00398 { 00399 /* 100MBit mode. */ 00400 LPC_EMAC->SUPP = SUPP_SPEED; 00401 } 00402 } 00403 return lReturn; 00404 } 00405 //-------------------------------------------------------------------------------- 00406 // ISR 00407 //-------------------------------------------------------------------------------- 00408 00409 /** 00410 * EMACからのハンドラ 00411 */ 00412 static void emacIsrHandler(unsigned long i_status) 00413 { 00414 if( i_status & INT_RX_DONE ) 00415 { 00416 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_RX); 00417 } 00418 if( i_status & INT_TX_DONE ) 00419 { 00420 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_TX); 00421 } 00422 } 00423 00424 #endif 00425 00426
Generated on Tue Jul 12 2022 15:46:14 by 1.7.2