This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
EtherDev_DP83848C.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 #include "NyLPC_config.h" 00061 #if NyLPC_MCU==NyLPC_MCU_LPC17xx 00062 00063 00064 /* Kernel includes. */ 00065 #include "../NyLPC_cEthernetMM.h" 00066 #include "EtherDev_DP83848C_protected.h" 00067 #include "LPC17xx.h" 00068 #include "NyLPC_os.h" 00069 00070 00071 #define DP83848C_ID 0x20005C90 /* PHY Identifier */ 00072 00073 /* DP83848C PHY Registers */ 00074 #define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ 00075 #define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ 00076 #define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ 00077 #define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ 00078 #define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ 00079 #define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ 00080 #define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ 00081 #define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ 00082 00083 /* PHY Extended Registers */ 00084 #define PHY_REG_STS 0x10 /* Status Register */ 00085 #define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ 00086 #define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ 00087 #define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ 00088 #define PHY_REG_RECR 0x15 /* Receive Error Counter */ 00089 #define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ 00090 #define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ 00091 #define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ 00092 #define PHY_REG_PHYCR 0x19 /* PHY Control Register */ 00093 #define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ 00094 #define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ 00095 #define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ 00096 00097 #define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ 00098 #define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ 00099 #define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ 00100 #define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ 00101 #define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ 00102 #define PHY_AUTO_NEG_COMPLETE 0x0020 /* Auto negotiation have finished. */ 00103 //#define ETHDEV_PHY_DEF_ADR 0x0100 /* Default PHY device address */ 00104 00105 00106 #ifndef configEMAC_INTERRUPT_PRIORITY 00107 #define configEMAC_INTERRUPT_PRIORITY 5 00108 #endif 00109 00110 /* Time to wait between each inspection of the link status. */ 00111 #define emacWAIT_FOR_LINK_TO_ESTABLISH_MS 500 00112 00113 /* Short delay used in several places during the initialisation process. */ 00114 #define emacSHORT_DELAY_MS 10 00115 00116 /* Hardware specific bit definitions. */ 00117 #define emacPINSEL2_VALUE ( 0x50150105 ) 00118 00119 00120 00121 /*-----------------------------------------------------------*/ 00122 00123 /* Setup the IO and peripherals required for Ethernet communication.*/ 00124 static void prvSetupEMACHardware( void ); 00125 /* Control the auto negotiate process.*/ 00126 static void prvConfigurePHY( void ); 00127 /* 00128 * Wait for a link to be established, then setup the PHY according to the link 00129 * parameters. 00130 */ 00131 static NyLPC_TBool prvSetupLinkStatus( void ); 00132 00133 00134 00135 00136 00137 static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param); 00138 static void stop(void); 00139 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); 00140 static void releaseTxBuf(void* i_buf); 00141 /*-----------------------------------------------------------*/ 00142 #define ETH_TX_BUF_BASE (void*)(ETH_BUF_BASE+ETH_FRAG_SIZE*NUM_RX_FRAG) 00143 00144 00145 const static struct TiEthernetDevice _interface= 00146 { 00147 "DP83848C", 00148 start, 00149 stop, 00150 EthDev_LPC17xx_getRxEthFrame, 00151 EthDev_LPC17xx_nextRxEthFrame, 00152 allocTxBuf, 00153 releaseTxBuf, 00154 EthDev_LPC17xx_sendTxEthFrame, 00155 EthDev_LPC17xx_processTx 00156 }; 00157 00158 static void* _event_param; 00159 static NyLPC_TiEthernetDevice_onEvent _event_handler; 00160 00161 /** EMAC ISRハンドラ*/ 00162 static void emacIsrHandler(unsigned long i_status); 00163 00164 /* 00165 * EthernetDeviceのファクトリー関数 00166 */ 00167 00168 NyLPC_TBool EthDev_DP83848C_getInterface( 00169 const struct TiEthernetDevice** o_dev) 00170 { 00171 unsigned long ulID1, ulID2; 00172 NyLPC_TBool lReturn = NyLPC_TBool_TRUE; 00173 //Reset MCU Interface. and wait for reset. 00174 prvSetupEMACHardware(); 00175 //Check peripheral name 00176 ulID1 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR1, &lReturn ); 00177 ulID2 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR2, &lReturn ); 00178 if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) != DP83848C_ID) 00179 { 00180 return NyLPC_TBool_FALSE; 00181 } 00182 *o_dev=&_interface; 00183 LPC_EMAC->TxProduceIndex = 0; 00184 LPC_EMAC->RxConsumeIndex = 0; 00185 return NyLPC_TBool_TRUE; 00186 } 00187 00188 00189 static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param) 00190 { 00191 _event_handler=i_handler; 00192 _event_param=i_param; 00193 NyLPC_cIsr_setEnetISR(emacIsrHandler); 00194 /* Set the Ethernet MAC Address registers */ 00195 LPC_EMAC->SA0 = (((uint32_t)(i_eth_addr->addr[0])) << 8 ) | i_eth_addr->addr[1]; 00196 LPC_EMAC->SA1 = (((uint32_t)(i_eth_addr->addr[2])) << 8 ) | i_eth_addr->addr[3]; 00197 LPC_EMAC->SA2 = (((uint32_t)(i_eth_addr->addr[4])) << 8 ) | i_eth_addr->addr[5]; 00198 00199 //TXメモリマネージャの準備 00200 NyLPC_cEthernetMM_initialize(ETH_TX_BUF_BASE); 00201 00202 /* Initialize Tx and Rx DMA Descriptors */ 00203 EthDev_LPC17xx_prevRxDescriptor(); 00204 EthDev_LPC17xx_prevTxDescriptor(); 00205 00206 /* Setup the PHY. */ 00207 prvConfigurePHY(); 00208 00209 //wait for Link up... 00210 while(!prvSetupLinkStatus()) 00211 { 00212 NyLPC_cThread_sleep(100); 00213 } 00214 00215 /* Receive Broadcast and Perfect Match Packets */ 00216 LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN | RFC_MCAST_EN; 00217 00218 //Ethernetの割込み開始設定 00219 NyLPC_cIsr_enterCritical(); 00220 { 00221 /* Reset all interrupts */ 00222 LPC_EMAC->IntClear = 0xffff; 00223 LPC_EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE ); 00224 00225 /* Enable receive and transmit mode of MAC Ethernet core */ 00226 LPC_EMAC->Command |= ( CR_RX_EN | CR_TX_EN ); 00227 LPC_EMAC->MAC1 |= MAC1_REC_EN; 00228 00229 /* Set the interrupt priority to the max permissible to cause some 00230 interrupt nesting. */ 00231 NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY ); 00232 00233 /* Enable the interrupt. */ 00234 NVIC_EnableIRQ( ENET_IRQn ); 00235 } 00236 NyLPC_cIsr_exitCritical(); 00237 00238 return NyLPC_TBool_TRUE; 00239 00240 } 00241 static void stop(void) 00242 { 00243 NyLPC_cIsr_enterCritical(); 00244 { 00245 LPC_EMAC->IntEnable = (~(INT_RX_DONE|INT_TX_DONE))&LPC_EMAC->IntEnable; 00246 NVIC_DisableIRQ( ENET_IRQn ); 00247 } 00248 NyLPC_cIsr_exitCritical(); 00249 LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN ); 00250 LPC_EMAC->MAC1 &= ~MAC1_REC_EN; 00251 //ISR割り込み解除 00252 NyLPC_cIsr_setEnetISR(NULL); 00253 //TXメモリマネージャの終了 00254 NyLPC_cEthernetMM_finalize(); 00255 return; 00256 } 00257 00258 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) 00259 { 00260 return NyLPC_cEthernetMM_alloc(i_hint,o_size); 00261 } 00262 static void releaseTxBuf(void* i_buf) 00263 { 00264 NyLPC_cEthernetMM_release(i_buf); 00265 } 00266 00267 00268 00269 /******************************************************************************** 00270 * Private functions 00271 *******************************************************************************/ 00272 00273 /*-----------------------------------------------------------*/ 00274 00275 /*-----------------------------------------------------------*/ 00276 00277 static void prvSetupEMACHardware( void ) 00278 { 00279 unsigned short us; 00280 long x; 00281 NyLPC_TBool lDummy; 00282 00283 /* Power Up the EMAC controller. */ 00284 LPC_SC->PCONP |= 0x40000000; 00285 NyLPC_cThread_sleep( emacSHORT_DELAY_MS); 00286 00287 /* Enable P1 Ethernet Pins. */ 00288 LPC_PINCON->PINSEL2 = emacPINSEL2_VALUE; 00289 LPC_PINCON->PINSEL3 = ( LPC_PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005; 00290 00291 /* Reset all EMAC internal modules. */ 00292 LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; 00293 LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES| CR_PASS_RUNT_FRM; 00294 /* A short delay after reset. */ 00295 NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); 00296 00297 /* Initialize MAC control registers. */ 00298 LPC_EMAC->MAC1 = MAC1_PASS_ALL; 00299 LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; 00300 LPC_EMAC->MAXF = ETH_MAX_FLEN; 00301 LPC_EMAC->CLRT = CLRT_DEF; 00302 LPC_EMAC->IPGR = IPGR_DEF; 00303 00304 /*PCLK=18MHz, clock select=6, MDC=18/6=3MHz */ // I don't think so! 00305 /* Enable Reduced MII interface. */ 00306 LPC_EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII; 00307 NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); 00308 LPC_EMAC->MCFG = MCFG_CLK_DIV20; 00309 00310 /* Enable Reduced MII interface. */ 00311 LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT; 00312 00313 /* Reset Reduced MII Logic. */ 00314 LPC_EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED; 00315 NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); 00316 LPC_EMAC->SUPP = SUPP_SPEED; 00317 00318 /* Put the PHY in reset mode */ 00319 EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); 00320 NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5); 00321 00322 /* Wait for hardware reset to end. */ 00323 for( x = 0; x < 100; x++ ) 00324 { 00325 NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); 00326 us = EthDev_LPC17xx_prvReadPHY( PHY_REG_BMCR, &lDummy ); 00327 if( !( us & MCFG_RES_MII ) ) 00328 { 00329 /* Reset complete */ 00330 break; 00331 } 00332 } 00333 } 00334 /*------------------------------------------------ 00335 * Private function depend on device. 00336 * デバイス依存部分 00337 ------------------------------------------------*/ 00338 00339 00340 /*for mbed 00341 */ 00342 #define emacLINK_ESTABLISHED ( 0x0001 ) 00343 #define emacFULL_DUPLEX_ENABLED ( 0x0004 ) 00344 #define emac10BASE_T_MODE ( 0x0002 ) 00345 00346 00347 static void prvConfigurePHY( void ) 00348 { 00349 unsigned short us; 00350 long x; 00351 NyLPC_TBool lDummy; 00352 00353 /* Auto negotiate the configuration. */ 00354 if( EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) 00355 { 00356 NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); 00357 00358 for( x = 0; x < 10; x++ ) 00359 { 00360 us = EthDev_LPC17xx_prvReadPHY( PHY_REG_BMSR, &lDummy ); 00361 00362 if( us & PHY_AUTO_NEG_COMPLETE ) 00363 { 00364 break; 00365 } 00366 00367 NyLPC_cThread_sleep( emacWAIT_FOR_LINK_TO_ESTABLISH_MS); 00368 } 00369 } 00370 } 00371 00372 static NyLPC_TBool prvSetupLinkStatus( void ) 00373 { 00374 NyLPC_TBool lReturn = NyLPC_TBool_FALSE; 00375 long x; 00376 unsigned short usLinkStatus; 00377 00378 /* Wait with timeout for the link to be established. */ 00379 for( x = 0; x < 10; x++ ) 00380 { 00381 usLinkStatus = EthDev_LPC17xx_prvReadPHY( PHY_REG_STS, &lReturn ); 00382 if( usLinkStatus & emacLINK_ESTABLISHED ) 00383 { 00384 /* Link is established. */ 00385 lReturn = NyLPC_TBool_TRUE; 00386 break; 00387 } 00388 00389 NyLPC_cThread_sleep( emacWAIT_FOR_LINK_TO_ESTABLISH_MS); 00390 } 00391 00392 if( lReturn == NyLPC_TBool_TRUE ) 00393 { 00394 /* Configure Full/Half Duplex mode. */ 00395 if( usLinkStatus & emacFULL_DUPLEX_ENABLED ) 00396 { 00397 /* Full duplex is enabled. */ 00398 LPC_EMAC->MAC2 |= MAC2_FULL_DUP; 00399 LPC_EMAC->Command |= CR_FULL_DUP; 00400 LPC_EMAC->IPGT = IPGT_FULL_DUP; 00401 } 00402 else 00403 { 00404 /* Half duplex mode. */ 00405 LPC_EMAC->IPGT = IPGT_HALF_DUP; 00406 } 00407 00408 /* Configure 100MBit/10MBit mode. */ 00409 if( usLinkStatus & emac10BASE_T_MODE ) 00410 { 00411 /* 10MBit mode. */ 00412 LPC_EMAC->SUPP = 0; 00413 } 00414 else 00415 { 00416 /* 100MBit mode. */ 00417 LPC_EMAC->SUPP = SUPP_SPEED; 00418 } 00419 } 00420 00421 return lReturn; 00422 } 00423 00424 /** 00425 * EMACからのハンドラ 00426 */ 00427 static void emacIsrHandler(unsigned long i_status) 00428 { 00429 if( i_status & INT_RX_DONE ) 00430 { 00431 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_RX); 00432 } 00433 if( i_status & INT_TX_DONE ) 00434 { 00435 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_TX); 00436 } 00437 } 00438 00439 #endif
Generated on Tue Jul 12 2022 15:46:14 by 1.7.2