This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
EthDev_LPC4088.c
00001 #include "NyLPC_config.h" 00002 #if NyLPC_MCU==NyLPC_MCU_LPC4088 00003 #include "NyLPC_os.h" 00004 #include "copy_of_ethernet_api.h" 00005 #include "NyLPC_IEthernetDevice.h" 00006 #include "NyLPC_cEthernetMM.h" 00007 00008 00009 00010 #define emacSHORT_DELAY_MS 10 00011 #ifndef configEMAC_INTERRUPT_PRIORITY 00012 #define configEMAC_INTERRUPT_PRIORITY 5 00013 #endif 00014 //////////////////////////////////////////////////////////////////////////////// 00015 // Ethernet Memory 00016 //////////////////////////////////////////////////////////////////////////////// 00017 00018 #define AHB_SRAM_BANK1_BASE 0x20004000UL 00019 #define RX_DESC_BASE (AHB_SRAM_BANK1_BASE ) 00020 #define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */ 00021 #define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */ 00022 #define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */ 00023 #define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */ 00024 00025 /** 00026 * 消費メモリ量は、 00027 * descriptor = NUM_RX_FRAG*16+NUM_TX_FRAG*12. 00028 * EthnetBuf=ETH_FRAG_SIZE*NUM_RX_FRAG 00029 */ 00030 00031 /* RX and TX descriptor and status definitions. */ 00032 #define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) 00033 #define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) 00034 #define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) 00035 #define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) 00036 #define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) 00037 #define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) 00038 #define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) 00039 #define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i ) 00040 #define ETH_TX_BUF_BASE ((void*)(ETH_BUF_BASE+ETH_FRAG_SIZE*NUM_RX_FRAG)) 00041 00042 00043 #define emacWAIT_FOR_LINK_TO_ESTABLISH_MS 500 00044 00045 //////////////////////////////////////////////////////////////////////////////// 00046 // Ethernet interdface functions 00047 //////////////////////////////////////////////////////////////////////////////// 00048 static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param); 00049 static void stop(void); 00050 static void* getRxEthFrame(unsigned short* o_len_of_data); 00051 static void nextRxEthFrame(void); 00052 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); 00053 static void releaseTxBuf(void* i_buf); 00054 static void sendTxEthFrame(void* i_buf,unsigned short i_size); 00055 static void processTx(void); 00056 00057 //////////////////////////////////////////////////////////////////////////////// 00058 // Private 00059 //////////////////////////////////////////////////////////////////////////////// 00060 static void emacIsrHandler(unsigned long i_status); 00061 static unsigned int clockselect(void); 00062 static int ethernet_link(void); 00063 static int phy_write(unsigned int PhyReg, unsigned short Data); 00064 static int phy_read(unsigned int PhyReg); 00065 static void prevTxDescriptor(void); 00066 static void prevRxDescriptor(void); 00067 static NyLPC_TUInt32 waitForTxEthFrameEmpty(void); 00068 00069 /*-----------------------------------------------------------*/ 00070 00071 00072 const static struct TiEthernetDevice _interface_LAN8720= 00073 { 00074 "LAN8720", 00075 start, 00076 stop, 00077 getRxEthFrame, 00078 nextRxEthFrame, 00079 allocTxBuf, 00080 releaseTxBuf, 00081 sendTxEthFrame, 00082 processTx 00083 }; 00084 const static struct TiEthernetDevice _interface_DP83848C= 00085 { 00086 "DP83848C", 00087 start, 00088 stop, 00089 getRxEthFrame, 00090 nextRxEthFrame, 00091 allocTxBuf, 00092 releaseTxBuf, 00093 sendTxEthFrame, 00094 processTx 00095 }; 00096 00097 static void* _event_param; 00098 static NyLPC_TiEthernetDevice_onEvent _event_handler; 00099 static unsigned int phy_id; 00100 00101 /* 00102 * EthernetDeviceのファクトリー関数。インターフェイスを生成できればtrue 00103 * 00104 */ 00105 NyLPC_TBool EthDev_LPC4088_getInterface( 00106 const struct TiEthernetDevice** o_dev) 00107 { 00108 int regv, tout; 00109 unsigned int clock = clockselect(); 00110 00111 LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ 00112 LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ 00113 LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */ 00114 LPC_IOCON->P1_1 &= ~0x07; 00115 LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */ 00116 LPC_IOCON->P1_4 &= ~0x07; 00117 LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */ 00118 LPC_IOCON->P1_8 &= ~0x07; 00119 LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */ 00120 LPC_IOCON->P1_9 &= ~0x07; 00121 LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */ 00122 LPC_IOCON->P1_10 &= ~0x07; 00123 LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */ 00124 LPC_IOCON->P1_14 &= ~0x07; 00125 LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */ 00126 LPC_IOCON->P1_15 &= ~0x07; 00127 LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */ 00128 LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ 00129 LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */ 00130 LPC_IOCON->P1_17 &= ~0x07; 00131 LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */ 00132 00133 /* Reset all EMAC internal modules. */ 00134 LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; 00135 LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; 00136 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00137 00138 /* Initialize MAC control registers. */ 00139 LPC_EMAC->MAC1 = MAC1_PASS_ALL; 00140 LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; 00141 LPC_EMAC->MAXF = ETH_MAX_FLEN; 00142 LPC_EMAC->CLRT = CLRT_DEF; 00143 LPC_EMAC->IPGR = IPGR_DEF; 00144 00145 /* Enable Reduced MII interface. */ 00146 LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ 00147 LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ 00148 LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM |CR_PASS_RX_FILT; /* Enable Reduced MII interface. */ 00149 00150 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00151 00152 LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; 00153 LPC_EMAC->MCMD = 0; 00154 LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ 00155 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00156 LPC_EMAC->SUPP = SUPP_SPEED; 00157 00158 phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ 00159 for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ 00160 regv = phy_read(PHY_REG_BMCR); 00161 if(regv < 0 || tout == 0) { 00162 return NyLPC_TBool_FALSE; /* Error */ 00163 } 00164 if(!(regv & PHY_BMCR_RESET)) { 00165 break; /* Reset complete. */ 00166 } 00167 } 00168 00169 phy_id = (phy_read(PHY_REG_IDR1) << 16); 00170 phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); 00171 00172 switch(phy_id){ 00173 case DP83848C_ID: 00174 *o_dev=&_interface_DP83848C; 00175 break; 00176 case LAN8720_ID: 00177 *o_dev=&_interface_LAN8720; 00178 break; 00179 default: 00180 return NyLPC_TBool_FALSE; /* Error */ 00181 } 00182 LPC_EMAC->TxProduceIndex = 0; 00183 LPC_EMAC->RxConsumeIndex = 0; 00184 return NyLPC_TBool_TRUE; 00185 } 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 int i; 00192 //ISRw割り込み設定 00193 NyLPC_cIsr_setEnetISR(emacIsrHandler); 00194 _event_handler=i_handler; 00195 _event_param=i_param; 00196 /* Set the Ethernet MAC Address registers */ 00197 LPC_EMAC->SA0 = (((uint32_t)(i_eth_addr->addr[0])) << 8 ) | i_eth_addr->addr[1]; 00198 LPC_EMAC->SA1 = (((uint32_t)(i_eth_addr->addr[2])) << 8 ) | i_eth_addr->addr[3]; 00199 LPC_EMAC->SA2 = (((uint32_t)(i_eth_addr->addr[4])) << 8 ) | i_eth_addr->addr[5]; 00200 00201 //TXメモリマネージャの準備 00202 NyLPC_cEthernetMM_initialize(ETH_TX_BUF_BASE); 00203 /* Initialize Tx and Rx DMA Descriptors */ 00204 prevRxDescriptor(); 00205 prevTxDescriptor(); 00206 //wait for link up 00207 for(i=0;i<5;i++){ 00208 if(ethernet_link()!=0){ 00209 break; 00210 } 00211 NyLPC_cThread_sleep(emacWAIT_FOR_LINK_TO_ESTABLISH_MS); 00212 } 00213 00214 //setup Link 00215 ethernet_set_link(-1, 0); 00216 00217 LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; 00218 /* Receive Broadcast, Perfect Match Packets */ 00219 00220 //Ethernetの割込み開始設定 00221 NyLPC_cIsr_enterCritical(); 00222 { 00223 LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ 00224 LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ 00225 00226 LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ 00227 LPC_EMAC->MAC1 |= MAC1_REC_EN; 00228 00229 NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY ); 00230 NVIC_EnableIRQ( ENET_IRQn ); 00231 } 00232 NyLPC_cIsr_exitCritical(); 00233 00234 return NyLPC_TBool_TRUE; 00235 } 00236 00237 00238 static void stop(void) 00239 { 00240 NyLPC_cIsr_enterCritical(); 00241 { 00242 LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); 00243 LPC_EMAC->IntClear = 0xFFFF; 00244 00245 NVIC_DisableIRQ( ENET_IRQn ); 00246 } 00247 NyLPC_cIsr_exitCritical(); 00248 LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN ); 00249 LPC_EMAC->MAC1 &= ~MAC1_REC_EN; 00250 //ISR割り込み解除 00251 NyLPC_cIsr_setEnetISR(NULL); 00252 //TXメモリマネージャの終了 00253 NyLPC_cEthernetMM_finalize(); 00254 } 00255 00256 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) 00257 { 00258 return NyLPC_cEthernetMM_alloc(i_hint,o_size); 00259 } 00260 static void releaseTxBuf(void* i_buf) 00261 { 00262 NyLPC_cEthernetMM_release(i_buf); 00263 } 00264 00265 00266 /** 00267 */ 00268 static void processTx(void) 00269 { 00270 waitForTxEthFrameEmpty(); 00271 } 00272 00273 00274 00275 /** 00276 * Ethernetパケットを送信します。 00277 * allocTxBufで得たバッファを指定すること。 00278 * <p>関数仕様</p> 00279 * この関数は、i_bufが 00280 * </div> 00281 */ 00282 static void sendTxEthFrame(void* i_buf,unsigned short i_size) 00283 { 00284 NyLPC_TUInt32 IndexNext,Index; 00285 struct NyLPC_TTxBufferHeader* bh=NyLPC_TTxBufferHeader_getBufferHeaderAddr(i_buf); 00286 00287 //サイズ0なら送信の必要なし 00288 if(i_size == 0) 00289 { 00290 return; 00291 } 00292 //送信デスクリプタの反映 00293 IndexNext =waitForTxEthFrameEmpty(); 00294 00295 //送信対象のメモリブロックを送信中に設定。 00296 // b=(i_buf+1); 00297 //送信中のメモリブロックなら無視 00298 if(bh->is_lock){ 00299 return; 00300 } 00301 //送信中にセット 00302 bh->is_lock=NyLPC_TUInt8_TRUE; 00303 00304 //送信データのセット 00305 Index = LPC_EMAC->TxProduceIndex; 00306 if (i_size > ETH_FRAG_SIZE){ 00307 i_size = ETH_FRAG_SIZE; 00308 } 00309 //送信処理 00310 TX_DESC_PACKET( Index ) = ( unsigned long )i_buf; 00311 //See UM10360.pdf Table 181. Transmit descriptor control word 00312 TX_DESC_CTRL( Index ) = ((i_size-1) | TCTRL_LAST | TCTRL_INT ); 00313 LPC_EMAC->TxProduceIndex = IndexNext; 00314 return; 00315 } 00316 /** 00317 * 送信デスクリプタを準備します。 00318 */ 00319 static void prevTxDescriptor(void) 00320 { 00321 long x; 00322 //デスクリプタの設定 00323 for( x = 0; x < NUM_TX_FRAG; x++ ) 00324 { 00325 TX_DESC_PACKET( x ) = ( unsigned long ) NULL; 00326 TX_DESC_CTRL( x ) = 0; 00327 TX_STAT_INFO( x ) = 0; 00328 } 00329 /* Set LPC_EMAC Transmit Descriptor Registers. */ 00330 LPC_EMAC->TxDescriptor =TX_DESC_BASE; 00331 LPC_EMAC->TxStatus = TX_STAT_BASE; 00332 LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1; 00333 } 00334 static void prevRxDescriptor(void) 00335 { 00336 int x; 00337 //デスクリプタの設定 00338 for( x = 0; x < NUM_RX_FRAG; x++ ) 00339 { 00340 /* Allocate the next Ethernet buffer to this descriptor. */ 00341 RX_DESC_PACKET(x) = ETH_BUF(x); 00342 RX_DESC_CTRL(x) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 ); 00343 RX_STAT_INFO(x) = 0; 00344 RX_STAT_HASHCRC(x) = 0; 00345 } 00346 00347 /* Set LPC_EMAC Receive Descriptor Registers. */ 00348 LPC_EMAC->RxDescriptor = RX_DESC_BASE; 00349 LPC_EMAC->RxStatus = RX_STAT_BASE; 00350 LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1; 00351 00352 } 00353 00354 00355 /** 00356 * 受信キューの先頭にあるRXフレームのポインタを返します。 00357 * 関数は、受信キューのポインタを操作しません。続けて読み出したとしても、同じポインターを返します。 00358 * 制限として、返却したポインタの内容は、一時的に書き換え可としてください。(この制限は将来削除します。) 00359 * @return 00360 * 成功した場合、受信データを格納したバッファポインターです。 00361 * 次回nextRxEthFrameを呼び出すまで有効です。 00362 */ 00363 static void* getRxEthFrame(unsigned short* o_len_of_data) 00364 { 00365 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) 00366 { 00367 //受信データを返却する。 00368 *o_len_of_data = (unsigned short)(( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3); 00369 return ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex ); 00370 } 00371 return NULL; 00372 } 00373 00374 00375 /** 00376 * 受信キューを進行します。 00377 */ 00378 static void nextRxEthFrame(void) 00379 { 00380 long lIndex; 00381 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) 00382 { 00383 //キューすすめる。 00384 lIndex = LPC_EMAC->RxConsumeIndex; 00385 lIndex++; 00386 if( lIndex >= NUM_RX_FRAG ) 00387 { 00388 lIndex = 0; 00389 } 00390 LPC_EMAC->RxConsumeIndex = lIndex; 00391 } 00392 } 00393 /******************************************************************************** 00394 * Private functions 00395 *******************************************************************************/ 00396 00397 00398 00399 /** 00400 * 送信中のイーサフレームを処理する機会を与えて、送信キューが空くまで待ちます。 00401 * LPC1769の場合は、非同期に更新したディスクリプタの内容から、送信メモリのフラグを更新します。 00402 * @return 00403 * 次に書き込むことが出来る送信キュー。 00404 */ 00405 static NyLPC_TUInt32 waitForTxEthFrameEmpty(void) 00406 { 00407 NyLPC_TUInt32 IndexNext; 00408 struct NyLPC_TTxBufferHeader *b; 00409 void* p; 00410 NyLPC_TUInt32 i; 00411 00412 //送信キューの決定 00413 IndexNext = (LPC_EMAC->TxProduceIndex + 1)%NUM_TX_FRAG; 00414 00415 //送信キューフルが解除されるまで待ち 00416 while(IndexNext == LPC_EMAC->TxConsumeIndex) 00417 { 00418 // 00419 NyLPC_cThread_sleep(emacSHORT_DELAY_MS); 00420 } 00421 00422 //(TxProduceIndex+1)→TxConsumeIndexにあるデータのsentフラグを消去 00423 for(i=IndexNext;i!=LPC_EMAC->TxConsumeIndex;i=(i+1)%NUM_TX_FRAG) 00424 { 00425 p=(void*)TX_DESC_PACKET(i); 00426 if(p!=NULL){ 00427 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); 00428 b->is_lock=NyLPC_TUInt8_FALSE; 00429 TX_DESC_PACKET(i)=0; 00430 } 00431 } 00432 p=(void*)TX_DESC_PACKET(i); 00433 if(p!=NULL){ 00434 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); 00435 b->is_lock=NyLPC_TUInt8_FALSE; 00436 TX_DESC_PACKET(i)=0; 00437 } 00438 return IndexNext; 00439 } 00440 00441 //-------------------------------------------------------------------------------- 00442 // ISR 00443 //-------------------------------------------------------------------------------- 00444 00445 static void ethernet_set_link(int speed, int duplex) { 00446 unsigned short phy_data; 00447 int tout; 00448 00449 if((speed < 0) || (speed > 1)) { 00450 phy_data = PHY_AUTO_NEG; 00451 } else { 00452 phy_data = (((unsigned short) speed << 13) | 00453 ((unsigned short) duplex << 8)); 00454 } 00455 00456 phy_write(PHY_REG_BMCR, phy_data); 00457 00458 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00459 00460 switch(phy_id) { 00461 case DP83848C_ID: 00462 phy_data = phy_read(PHY_REG_STS); 00463 00464 if(phy_data & PHY_STS_DUPLEX) { 00465 LPC_EMAC->MAC2 |= MAC2_FULL_DUP; 00466 LPC_EMAC->Command |= CR_FULL_DUP; 00467 LPC_EMAC->IPGT = IPGT_FULL_DUP; 00468 } else { 00469 LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; 00470 LPC_EMAC->Command &= ~CR_FULL_DUP; 00471 LPC_EMAC->IPGT = IPGT_HALF_DUP; 00472 } 00473 00474 if(phy_data & PHY_STS_SPEED) { 00475 LPC_EMAC->SUPP &= ~SUPP_SPEED; 00476 } else { 00477 LPC_EMAC->SUPP |= SUPP_SPEED; 00478 } 00479 break; 00480 00481 case LAN8720_ID: 00482 phy_data = phy_read(PHY_REG_SCSR); 00483 00484 if (phy_data & PHY_SCSR_DUPLEX) { 00485 LPC_EMAC->MAC2 |= MAC2_FULL_DUP; 00486 LPC_EMAC->Command |= CR_FULL_DUP; 00487 LPC_EMAC->IPGT = IPGT_FULL_DUP; 00488 } else { 00489 LPC_EMAC->Command &= ~CR_FULL_DUP; 00490 LPC_EMAC->IPGT = IPGT_HALF_DUP; 00491 } 00492 00493 if(phy_data & PHY_SCSR_100MBIT) { 00494 LPC_EMAC->SUPP |= SUPP_SPEED; 00495 } else { 00496 LPC_EMAC->SUPP &= ~SUPP_SPEED; 00497 } 00498 00499 break; 00500 } 00501 } 00502 00503 static int phy_write(unsigned int PhyReg, unsigned short Data) { 00504 unsigned int timeOut; 00505 00506 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; 00507 LPC_EMAC->MWTD = Data; 00508 00509 for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ 00510 if((LPC_EMAC->MIND & MIND_BUSY) == 0) { 00511 return 0; 00512 } 00513 } 00514 00515 return -1; 00516 } 00517 00518 00519 static int phy_read(unsigned int PhyReg) { 00520 unsigned int timeOut; 00521 00522 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; 00523 LPC_EMAC->MCMD = MCMD_READ; 00524 00525 for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ 00526 if((LPC_EMAC->MIND & MIND_BUSY) == 0) { 00527 LPC_EMAC->MCMD = 0; 00528 return LPC_EMAC->MRDD; /* Return a 16-bit value. */ 00529 } 00530 } 00531 00532 return -1; 00533 } 00534 00535 00536 //extern unsigned int SystemFrequency; 00537 static unsigned int clockselect(void) 00538 { 00539 if(SystemCoreClock < 10000000) { 00540 return 1; 00541 } else if(SystemCoreClock < 15000000) { 00542 return 2; 00543 } else if(SystemCoreClock < 20000000) { 00544 return 3; 00545 } else if(SystemCoreClock < 25000000) { 00546 return 4; 00547 } else if(SystemCoreClock < 35000000) { 00548 return 5; 00549 } else if(SystemCoreClock < 50000000) { 00550 return 6; 00551 } else if(SystemCoreClock < 70000000) { 00552 return 7; 00553 } else if(SystemCoreClock < 80000000) { 00554 return 8; 00555 } else if(SystemCoreClock < 90000000) { 00556 return 9; 00557 } else if(SystemCoreClock < 100000000) { 00558 return 10; 00559 } else if(SystemCoreClock < 120000000) { 00560 return 11; 00561 } else if(SystemCoreClock < 130000000) { 00562 return 12; 00563 } else if(SystemCoreClock < 140000000) { 00564 return 13; 00565 } else if(SystemCoreClock < 150000000) { 00566 return 15; 00567 } else if(SystemCoreClock < 160000000) { 00568 return 16; 00569 } else { 00570 return 0; 00571 } 00572 } 00573 00574 static int ethernet_link(void) 00575 { 00576 00577 if (phy_id == DP83848C_ID) { 00578 return (phy_read(PHY_REG_STS) & PHY_STS_LINK); 00579 } 00580 else { // LAN8720_ID 00581 return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); 00582 } 00583 } 00584 //-------------------------------------------------------------------------------- 00585 // ISR 00586 //-------------------------------------------------------------------------------- 00587 00588 00589 /** 00590 * EMACからのハンドラ 00591 */ 00592 static void emacIsrHandler(unsigned long i_status) 00593 { 00594 if( i_status & INT_RX_DONE ) 00595 { 00596 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_RX); 00597 } 00598 if( i_status & INT_TX_DONE ) 00599 { 00600 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_TX); 00601 } 00602 } 00603 00604 #endif 00605 00606 00607
Generated on Tue Jul 12 2022 15:46:14 by 1.7.2